package org.fujene.memoryblock;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.UnsupportedEncodingException;

import org.fujene.constants.Constants;
import org.fujene.diskblock.AppendixDiskBlock;
import org.fujene.diskblock.DiskBlock;
import org.fujene.toolbox.ByteConverter;

/**
 * This block stores contents without analyze (i.e. URL, description)
 * @author fujisaka_yusuke
 */
public class AppendixBlock extends MemoryBlock{
	public static final int OPT_TYPE = 0;
	public static final int OPTSIZE = 1;
	private int opt_type = 0;
	
	public AppendixBlock(int bodySize, int ID, boolean isAllocate){
		super(bodySize, ID, Constants.MEMORY_TYPE_APPENDIX, isAllocate);
	}

	public AppendixBlock(byte[] block, int bodySize, int ID, boolean isAllocate){
		super(block, bodySize, ID, Constants.MEMORY_TYPE_APPENDIX, isAllocate);
	}

	public int setContent(int ptr, String str){
		try{
			byte[] strb = str.getBytes("UTF-8");

			setBody(ByteConverter.intToByte(strb.length, STRLEN), ptr);
			ptr += STRLEN;
			setBody(strb, ptr);
			return ptr + strb.length;
		}catch(UnsupportedEncodingException e){
			return -1;
		}
	}

	public String getContent(int ptr){
		try{
			int strlen = ByteConverter.byteToInt(getBody(ptr, STRLEN));
			ptr += STRLEN;
			return new String(getBody(ptr, strlen), "UTF-8");
		}catch(UnsupportedEncodingException e){}

		return null;
	}
	
	public int size(int ptr) {
		int strlen = ByteConverter.byteToInt(getBody(ptr, STRLEN));
		return STRLEN + strlen;
	}

	public void delete(int ptr){
		setBody(ByteConverter.intToByte(-1, STRLEN), ptr);
	}

	public int getNewPointer(String str){
		try{
			byte[] strb = str.getBytes("UTF-8");
			int returnPtr = this.bodySize - this.bodyVacancy;
			if(this.bodyVacancy >= STRLEN + strb.length){
				this.bodyVacancy -= STRLEN + strb.length;
				return returnPtr;
			}else{
				return -1;
			}
		}catch(UnsupportedEncodingException e){
			return -1;
		}
	}

	public static byte[] createByteArray(String str) throws IOException{
		byte[] barray = str.getBytes("UTF-8");
		ByteArrayOutputStream stream = new ByteArrayOutputStream();

		stream.write(ByteConverter.intToByte(barray.length, STRLEN));

		stream.write(barray);

		return stream.toByteArray();
	}

	public byte[] getData() throws IOException{
		ByteArrayOutputStream stream = new ByteArrayOutputStream(this.bodySize + 4);

		stream.write(getOptionByteStream());
		stream.write(this.getBody(0, this.bodySize));

		return stream.toByteArray();
	}

	public void setData(byte[] array){
		setBody(array, 0, bodySize, 0);
	}

	public int getSupplementIndex(){
		return opt_type;
	}

	@Override
	public int getOptionSize(){
		return OPTSIZE;
	}

	@Override
	public byte[] getOptionByteStream(){
		return ByteConverter.intToByte(opt_type, 4);
	}

	@Override
	public int getOption(int num){
		if(num == 0) return opt_type;
		else return 0;
	}

	@Override
	public void setOption(int option, int value){
		if(option == 0) opt_type = value;
	}

	@Override
	public String getClassName(){
		return new String("PureContentBlock");
	}

	@Override
	public DiskBlock toDisk(int from, int to, String dir){
		AppendixDiskBlock diskblock = new AppendixDiskBlock(this, dir);
		diskblock.save(from, to, dir);
		
		return diskblock;
	}
}
